#
# Sorto, the sorting game
# Copyright (C) 2012 Ralph Preston
# ralph.preston@gmail.com
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to:
#
# Free Software Foundation, Inc.
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301
# USA.
#
import threading

from sorto_controller import SortoController
from sorto_record     import SortoRecord

class SortoBaseView(object):
    OFF_BOARD_COUNTER = 'off board counter'
    BOARD_COUNTER     = 'board counter'

    def __init__(self, max_games, logfile, append=False, verbosity=2):
        self._max_games     = 0
        self._game_number   = 0
        self._player_records   = {} # map player names to their score
        self._player_counters  = {} # map player name to a history of counters
        self._player_counter_colors = {} # map player name to their color
        self._round         = 0
        self._callback_lock = threading.Lock()
        self.max_games      = max_games
        self.logfile        = logfile
        self.append         = append
        self.verbosity      = 2
        self.player_files        = {}
        self.remote_player_files = {}
        self.controller = SortoController(view=self, 
                                          logfile=self.logfile, 
                                          append=self.append, 
                                          verbosity=self.verbosity)
        return

    def load_remote_player(self, player_name, remote_server):
        """
        Registers the player with a remote server. The remote server
        controls the simulation. The players are registered with the
        remote server and the remote server calls the player's
        play_game_turn method.
        """
        self.remote_player_files[player_name] = remote_server
        self.controller.load_remote_player(player_name, remote_server)
        return

    def unload_remote_players(self):
        """
        Un-registers remote players from the server.
        """
        self.remote_player_files = {}
        self.controller.unregister_remote_players()
        return

    def get_max_games(self):
        return self.max_games

    def set_game_number(self, game_number):
        self._game_number = game_number
        for player in self._player_records:
            self._player_records[player].new_game()
            pass
        return

    def set_round(self, round):
        self._round = round
        return

    def set_board_state(self, player, player_colors, board, counters):
        if player not in self._player_boards:
            self._player_boards[player]   = [ ]
            self._player_counters[player] = [ ]
            pass
        self._player_counters[player] = counters
        self._player_boards[player]   = board
        self._player_counter_colors   = player_colors
        return
    
    def choose_counter(self, player_name, counter_from):
        # Make sure the current player's board is displayed
        self.display_board_for_player(player_name)
        counter = self.get_counter_from(counter_from)
        return counter

    def set_player_color(self, player_name, color):
        return

    def display_board_for_player(self, player_name):
        """
        The view should display the specified player's board.
        """
        raise Exception("This method must be defined by child views")
    
    def get_counter_from(self, location):
        """
        The view should let the player choose a counter to play from
        the location specified.  The location is either
        self.OFF_BOARD_COUNTER or self.BOARD_COUNTER.

        The method returns the counter number.
        """
        raise Exception("This method must be defined by child views")

    pass # End of class SortoBaseView
